home *** CD-ROM | disk | FTP | other *** search
/ Nebula 1 / Nebula One.iso / Graphics / Plotting / aa_Intel_Only / Gnuplot / GnuplotSource / Inspector.m < prev    next >
Encoding:
Text File  |  1995-06-12  |  7.6 KB  |  390 lines

  1. /*
  2.  *  Copyright (C) 1993  Robert Davis
  3.  *
  4.  *  This program is free software; you can redistribute it and/or
  5.  *  modify it under the terms of Version 2, or any later version, of 
  6.  *  the GNU General Public License as published by the Free Software 
  7.  *  Foundation.
  8.  */
  9.  
  10. static char RCSId[]="$Id: Inspector.m,v 1.13 1993/05/18 03:55:15 davis Exp $";
  11.  
  12.  
  13. #import <appkit/Application.h>
  14. #import <appkit/Button.h>
  15. #import <appkit/Matrix.h>
  16. #import <appkit/Panel.h>
  17. #import <appkit/Pasteboard.h>
  18. #import <appkit/publicWraps.h>    /* NXBeep()        */
  19.  
  20. #import <dpsclient/wraps.h>
  21.  
  22. #import "AxesPane.h"
  23. #import "DataPane.h"
  24. #import "GeneralPane.h"
  25. #import "Gnuplot.h"
  26. #import "GnuplotPlot.h"
  27. #import "Inspector.h"
  28. #import "NoPane.h"
  29. #import "Pane.h"
  30. #import "Status.h"
  31. #import "ThreeDPane.h"
  32.  
  33.  
  34. @interface Inspector (Private)
  35.  
  36. - _setupPane:(Pane *)aPane;
  37. - _selectPane:(int)aPane;
  38. - _swapPane:(Pane *)new;
  39. - _determineNewStatusAndDoc;
  40. - _updateForce:(BOOL)force all:(BOOL)all;
  41.  
  42. @end
  43.  
  44.  
  45.  
  46. @implementation Inspector
  47.  
  48.  
  49. - init
  50. {
  51.     const char    *validSend[] = {NXAsciiPboardType, NULL};
  52.     const char    *validReturn[] = {NXAsciiPboardType, NULL};
  53.  
  54.     [super init];
  55.  
  56.     [NXApp loadNibSection: "Inspector.nib" 
  57.             owner: self
  58.         withNames: NO
  59.          fromZone: [self zone]];
  60.  
  61.     [window setFrameUsingName:"InspectorPanel"];
  62.     [window setFrameAutosaveName:"InspectorPanel"];
  63.  
  64.     [NXApp registerServicesMenuSendTypes: validSend
  65.                           andReturnTypes: validReturn];
  66.  
  67.     [[window contentView] allocateGState];
  68.  
  69.     return self;
  70. }
  71.  
  72.  
  73. - free
  74. {
  75.     [window free];
  76.     [noPane free];
  77.     [generalPane free];
  78.     [dataPane free];
  79.     [axesPane free];
  80.     [threeDPane free];
  81.  
  82.     return [super free];
  83. }
  84.  
  85.  
  86. - window
  87. {
  88.     return window;
  89. }
  90.  
  91.  
  92.  
  93. - showPane:sender
  94. {
  95.     if (status)
  96.     [self _selectPane:[sender selectedTag]];
  97.     return self;
  98. }
  99.  
  100.  
  101. /* 
  102.  *  Services.  The Inspector instance is the inspector panel's 
  103.  *  delegate, so these methods work when the inspector panel is the 
  104.  *  key window.  We pass service requests on to the current 
  105.  *  GnuplotPlot so that the filename of the current doc can always be 
  106.  *  offered to servers, even when the inspector is the key window.
  107.  */
  108. - validRequestorForSendType:(NXAtom)sendType andReturnType:(NXAtom) returnType
  109. {
  110.     return [gnuplotPlot validRequestorForSendType:sendType 
  111.                     andReturnType:returnType];
  112. }
  113.  
  114.  
  115. - (BOOL)writeSelectionToPasteboard:pboard types:(NXAtom *)types
  116. {
  117.     return [gnuplotPlot writeSelectionToPasteboard:pboard types:types];
  118. }
  119.  
  120.  
  121.  
  122. /* 
  123.  *  This method is similar to -windowDidUpdate except that it forces 
  124.  *  ALL panes to update instead of just allowing the current pane to 
  125.  *  possibly update.  This is necessary to keep a pane's OptionsPanels 
  126.  *  up-to-date even when that pane is not selected.  (This is only a 
  127.  *  problem after such operations as "Revert to Saved" when NXApp's 
  128.  *  delegate must send this method.)
  129.  */
  130. - update
  131. {
  132.     return [self _updateForce:YES all:YES];
  133. }
  134.  
  135.  
  136.  
  137. /*  
  138.  *  The user can force a plot by pressing the Plot button in the 
  139.  *  Inspector. 
  140.  */
  141. - doPlot:sender
  142. {
  143.     if (gnuplotPlot)
  144.     [gnuplotPlot plot:self];
  145.     else
  146.     NXBeep();
  147.  
  148.     return self;
  149. }
  150.  
  151.  
  152.  
  153. /*  
  154.  *  This method is similar to -update except that it updates only the 
  155.  *  current pane, and allows it to decide whether or not it should 
  156.  *  update itself instead of forcing it to update.
  157.  */
  158. - windowDidUpdate:sender
  159. {
  160.     return [self _updateForce:NO all:NO];
  161. }
  162.  
  163.  
  164.  
  165. - selectPane:(int)aPane
  166. {
  167.     if (aPane != NO_INSPECTOR)
  168.     [buttonMatrix selectCellWithTag:aPane];
  169.  
  170.     [self _selectPane:aPane];
  171.     return self;
  172. }
  173.  
  174.  
  175.  
  176. // Shuts up the compiler about unused RCSId
  177. - (const char *) rcsid
  178. {
  179.     return RCSId;
  180. }
  181.  
  182.  
  183. @end
  184.  
  185.  
  186. @implementation Inspector (Private)
  187.  
  188. - _setupPane:(Pane *)aPane
  189. {
  190.     if (aPane) {
  191.     View    *panesView = [aPane view];
  192.  
  193.     [[window contentView] addSubview: panesView];
  194.     [[panesView allocateGState] lockFocus];
  195.     [panesView unlockFocus];
  196.     [panesView moveTo:0:30];
  197.     }
  198.  
  199.     return self;
  200. }
  201.     
  202.  
  203. - _selectPane:(int)aPane
  204. {
  205.     if (![window isVisible])
  206.     [self _determineNewStatusAndDoc];
  207.  
  208.     if (!status)
  209.     aPane = NO_INSPECTOR;
  210.  
  211.     switch (aPane) {
  212.  
  213.     case GENERAL_INSPECTOR:
  214.     if (!generalPane) {
  215.         generalPane = [[GeneralPane allocFromZone:[self zone]] init];
  216.         [self _setupPane:generalPane];
  217.     }
  218.     [self _swapPane:generalPane];
  219.     break;
  220.  
  221.     case DATA_INSPECTOR:
  222.     if (!dataPane) {
  223.         dataPane = [[DataPane allocFromZone:[self zone]] init];
  224.         [self _setupPane:dataPane];
  225.     }
  226.     [self _swapPane:dataPane];
  227.     break;
  228.  
  229.     case AXES_INSPECTOR:
  230.     if (!axesPane) {
  231.         axesPane = [[AxesPane allocFromZone:[self zone]] init];
  232.         [self _setupPane:axesPane];
  233.     }
  234.     [self _swapPane:axesPane];
  235.     break;
  236.  
  237.     case THREED_INSPECTOR:
  238.     if (!threeDPane) {
  239.         threeDPane = [[ThreeDPane allocFromZone:[self zone]] init];
  240.         [self _setupPane:threeDPane];
  241.     }
  242.     [self _swapPane:threeDPane];
  243.     break;
  244.  
  245.     default:
  246.     if (!noPane) {
  247.         noPane = [[NoPane allocFromZone:[self zone]] init];
  248.         [self _setupPane:noPane];
  249.     }
  250.     [self _swapPane:noPane];
  251.     break;
  252.  
  253.     }
  254.  
  255.     return self;
  256. }
  257.  
  258.  
  259. - _swapPane:(Pane *)new
  260. {
  261.     /*  
  262.      *  If "new" is nil, we look at the button matrix
  263.      *  to determine which inspector to swap in.
  264.      */
  265.     
  266.     if (!new)
  267.     switch ([buttonMatrix selectedTag]) {
  268.     case GENERAL_INSPECTOR:
  269.         new = generalPane; break;
  270.     case DATA_INSPECTOR:
  271.         new = dataPane; break;
  272.     case AXES_INSPECTOR:
  273.         new = axesPane; break;
  274.     case THREED_INSPECTOR:
  275.         new = threeDPane; break;
  276.     default:
  277.         new = noPane; break;
  278.     }
  279.         
  280.  
  281.     /*  
  282.      *  Now, if the new pane is not already visible,
  283.      *  move it into the inspector panel.
  284.      */
  285.     
  286.     if (new != currentPane) {
  287.  
  288.     [[window contentView] replaceSubview:[currentPane view]
  289.                     with:[new view]];
  290.     [currentPane didSwapOut:self];
  291.     [[new didSwapIn:self] updateStatus:status doc:gnuplotPlot];
  292.     [window display];
  293.  
  294.     [window setTitle:[new title]];
  295.     [window setMiniwindowIcon:[new icon]];
  296.  
  297.     currentPane = new;
  298.  
  299.     }
  300.  
  301.     return self;
  302. }
  303.  
  304.  
  305. - _determineNewStatusAndDoc
  306. {
  307.     Window    *mainWindow = [NXApp mainWindow];
  308.  
  309.     /*  Set instance variables that indicate the current doc.  */
  310.  
  311.     if (mainWindow)  {
  312.     gnuplotPlot = [mainWindow delegate];
  313.     status = [gnuplotPlot status];
  314.     } else {
  315.     if (gnuplotPlot = [[NXApp delegate] currentDoc])
  316.         status = [gnuplotPlot status];
  317.     else
  318.         status = nil;
  319.     }
  320.  
  321.     return self;
  322. }
  323.  
  324.  
  325. - _updateForce:(BOOL)force all:(BOOL)all
  326. {
  327.     BOOL    needsRedisplay = NO;
  328.  
  329.     [self _determineNewStatusAndDoc];
  330.     [window disableDisplay];
  331.  
  332.     if (!status) {            /* No current selection        */
  333.  
  334.     [self selectPane:NO_INSPECTOR];
  335.     needsRedisplay = YES;
  336.  
  337.     } else {                /* Update/replace controls    */
  338.  
  339.     if (force) {
  340.  
  341.         if (all) {
  342.  
  343.         needsRedisplay = [noPane forceUpdateStatus:status
  344.                            doc:gnuplotPlot]? YES :NO;
  345.  
  346.         needsRedisplay = ([generalPane forceUpdateStatus:status
  347.                   doc:gnuplotPlot]? YES :NO) || needsRedisplay;
  348.  
  349.         needsRedisplay = ([dataPane forceUpdateStatus:status
  350.                   doc:gnuplotPlot]? YES :NO) || needsRedisplay;
  351.  
  352.         needsRedisplay = ([axesPane forceUpdateStatus:status
  353.                   doc:gnuplotPlot]? YES :NO) || needsRedisplay;
  354.  
  355.         needsRedisplay = ([threeDPane forceUpdateStatus:status
  356.                   doc:gnuplotPlot]? YES :NO) || needsRedisplay;
  357.  
  358.         } else
  359.  
  360.         needsRedisplay = [currentPane forceUpdateStatus:status
  361.                   doc:gnuplotPlot]? YES :NO;
  362.  
  363.     } else
  364.  
  365.         needsRedisplay = [currentPane updateStatus:status doc:gnuplotPlot]?
  366.                                 YES :NO;
  367.     if (currentPane == noPane)
  368.         [self selectPane:[buttonMatrix selectedTag]];
  369.  
  370.     }
  371.  
  372.     [window reenableDisplay];
  373.     if (needsRedisplay)
  374.     [window display];
  375.  
  376.     /* 
  377.      *  We disable the plot button if
  378.      *         1) No current status, or
  379.      *         2) Current plot's status reports that it can't plot
  380.      */
  381.     [plotButton setEnabled:status && [status canPlot]];
  382.     
  383.     return self;
  384.  
  385.  
  386.  
  387. }
  388.  
  389. @end
  390.